package com.lykj.llw.box.ui.activity

import android.content.Intent
import android.graphics.Paint
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.recyclerview.widget.LinearLayoutManager
import app.dinus.com.itemdecoration.LinearDividerItemDecoration
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.ScreenUtils
import com.google.gson.reflect.TypeToken
import com.gyf.immersionbar.BarHide
import com.gyf.immersionbar.ImmersionBar
import com.lykj.lib_base.base.BaseActivity
import com.lykj.lib_base.internal.extfun.clickWithTrigger
import com.lykj.lib_base.internal.utils.ToastUtils
import com.lykj.lib_base.net.http.CustomResponseBodyObserver
import com.lykj.lib_base.net.http.RetrofitManager
import com.lykj.llw.box.R
import com.lykj.llw.box.adapter.home.SearchGameAdapter
import com.lykj.llw.box.adapter.home.SearchRecommendAdapter
import com.lykj.llw.box.data.bean.response.SearchGameResponse
import com.lykj.llw.box.data.bean.response.SearchRecommendResponse
import com.lykj.llw.box.data.model.SearchHistoryModel
import com.lykj.llw.box.databinding.ActGameSearchBinding
import com.lykj.llw.box.utils.ViewUtils
import io.reactivex.disposables.Disposable
import me.jessyan.autosize.utils.AutoSizeUtils
import okhttp3.ResponseBody


/**
 * ================================================
 * 游戏搜索页面
 * ================================================
 *
 * @author gosha
 * @date 2023/12/1-17:25
 */
class GameSearchActivity : BaseActivity() {
    lateinit var binding: ActGameSearchBinding

    private val mGameAdapter = SearchGameAdapter()
    private val mGames = ArrayList<SearchGameResponse.DataDTO>()

    private val mRecommendAdapter = SearchRecommendAdapter()
    private val mRecommendGames = ArrayList<SearchRecommendResponse.DataDTO>()

    private var mTextWatcher: TextWatcher? = null
    private var mLabelLimitWidth = 0
    private var mPadding = 0

    val mHistoryRecord = ArrayList<SearchHistoryModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActGameSearchBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initUI()
        initData()
        setListener()
    }

    override fun initUI() {
        initGameRCV()
        initRecommendRCV()

        mPadding = AutoSizeUtils.dp2px(this, 10f)
        mLabelLimitWidth = ScreenUtils.getAppScreenWidth() - AutoSizeUtils.dp2px(this, 15f)
    }

    private fun initGameRCV() {
        val linearLayoutManager = LinearLayoutManager(this)
        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
        binding.rcvSearchGame.layoutManager = linearLayoutManager
        binding.rcvSearchGame.setHasFixedSize(true)
        mGameAdapter.data = mGames
        mGameAdapter.setOnItemClickListener { adapter, view, position ->
            val intent = Intent(this, GameDetailActivity::class.java)
            intent.putExtra("gid", mGames[position].gid)
            startActivity(intent)
        }

        val dividerItemDecoration = LinearDividerItemDecoration(
            this, LinearDividerItemDecoration.LINEAR_DIVIDER_VERTICAL
        )
        dividerItemDecoration.setDivider(
            resources.getDrawable(
                R.drawable.divider_10dp, resources.newTheme()
            )
        )
        binding.rcvSearchGame.addItemDecoration(dividerItemDecoration)
        binding.rcvSearchGame.adapter = mGameAdapter
    }

    private fun initRecommendRCV() {
        val linearLayoutManager = LinearLayoutManager(this)
        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
        binding.rcvRecommendGame.layoutManager = linearLayoutManager
        binding.rcvRecommendGame.setHasFixedSize(true)
        mRecommendAdapter.data = mRecommendGames
        mRecommendAdapter.setOnItemClickListener { adapter, view, position ->
            val intent = Intent(this, GameDetailActivity::class.java)
            intent.putExtra("gid", mRecommendGames[position].gameId)
            startActivity(intent)
        }
        binding.rcvRecommendGame.adapter = mRecommendAdapter
    }

    //搜索游戏
    private fun searchGame(gName: String) {
        RetrofitManager.instance.searchGame(gName,
            object : CustomResponseBodyObserver<ResponseBody>() {
                override fun onSubscribe(d: Disposable) {
                    addDisposables(this@GameSearchActivity, d)
                }

                override fun specificHandle(responseBody: String) {
                    val bean = GsonUtils.fromJson(responseBody, SearchGameResponse::class.java)

                    mGames.clear()
                    if (!bean.data.isNullOrEmpty()) {
                        mGames.addAll(bean.data!!)
                    } else {
                        ToastUtils.showShort(this@GameSearchActivity, "没有搜索到相关游戏")
                    }

                    binding.rcvSearchGame.visibility = View.VISIBLE
                    binding.cltSearch.visibility = View.GONE

                    mGameAdapter.notifyDataSetChanged()
                }

                override fun handleException(ret: String, msg: String?) {
                    msg?.let {
                        ToastUtils.showShort(this@GameSearchActivity, it)
                    }
                }
            })
    }

    //获取推荐游戏
    private fun obtainRecommendGame() {
        RetrofitManager.instance.obtainSearchRecommend(object :
            CustomResponseBodyObserver<ResponseBody>() {
            override fun onSubscribe(d: Disposable) {
                addDisposables(this@GameSearchActivity, d)
            }

            override fun specificHandle(responseBody: String) {
                val bean = GsonUtils.fromJson(responseBody, SearchRecommendResponse::class.java)
                mRecommendGames.clear()
                if (!bean.data.isNullOrEmpty()) {
                    mRecommendGames.addAll(bean.data!!)
                }

                mRecommendAdapter.notifyDataSetChanged()
            }

            override fun handleException(ret: String, msg: String?) {
                msg?.let {
                    ToastUtils.showShort(this@GameSearchActivity, it)
                }
            }
        })
    }

    override fun initData() {
        obtainLocalHistoryData()
        obtainRecommendGame()
    }

    //获取本地历史数据
    private fun obtainLocalHistoryData() {
        mHistoryRecord.clear()
        val jsonStr = SPUtils.getInstance("history").getString("searchHistory")
        if (!jsonStr.isNullOrEmpty()) {
            val list =
                GsonUtils.fromJson<ArrayList<SearchHistoryModel>>(
                    jsonStr,
                    object : TypeToken<ArrayList<SearchHistoryModel>>() {}.type
                )

            //排序关键词
            mHistoryRecord.addAll(list.sortedWith(compareBy { it.searchCount }).asReversed())
        }

        obtainLocalHistory()
    }

    //获取本地历史记录并展示
    private fun obtainLocalHistory() {
        //获取本地搜素历史记录
        //动态添加历史搜索关键字
        binding.lltLabelsContainer.removeAllViews()
        val lPaint = Paint()
        lPaint.textSize = AutoSizeUtils.sp2px(this, 13f).toFloat()

        var line = buildLinearLayout()
        var lineNum = 1
        val firstLineIndex = ArrayList<Int>()
        firstLineIndex.add(0)

        for (i in mHistoryRecord.indices) {
            val label = buildLabel(mHistoryRecord[i].searchWord)
            if (judgmentNeedNewLine(lPaint, mHistoryRecord, i, firstLineIndex, lineNum)) {
                binding.lltLabelsContainer.addView(line)
                if (i < mHistoryRecord.size) {
                    firstLineIndex.add(i + 1)
                }
                lineNum++
                line = buildLinearLayout()
                line.addView(label)
            } else {
                line.addView(label)
            }

            if (i == mHistoryRecord.size - 1) {
                binding.lltLabelsContainer.addView(line)
            }
        }
    }

    //构建标签
    private fun buildLabel(text: String): View {
        val label = TextView(this)
        val lps = LinearLayoutCompat.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            AutoSizeUtils.dp2px(this, 35f)
        )
        lps.setMargins(0, mPadding, mPadding, 0)
        label.gravity = Gravity.CENTER
        label.setPadding(mPadding, 0, mPadding, 0)
        label.layoutParams = lps
        label.text = text
        label.setTextColor(ColorUtils.string2Int("#666564"))
        label.textSize = 13f
        label.setBackgroundResource(R.drawable.shape_bg_half_fff5f6f8)
        //增加点击触发
        label.clickWithTrigger {
            for (index in 0 until mHistoryRecord.size) {
                if (it.text.toString() == mHistoryRecord[index].searchWord) {
                    mHistoryRecord[index].searchCount++
                    break
                }
            }
            //增加次数
            val str = GsonUtils.toJson(mHistoryRecord)
            SPUtils.getInstance("history").put("searchHistory", str, true)

            binding.etSearch.setText(it.text.toString())
            searchGame(it.text.toString())
        }
        return label
    }

    //构建换行容器
    private fun buildLinearLayout(): LinearLayoutCompat {
        val line = LinearLayoutCompat(this)
        line.orientation = LinearLayoutCompat.HORIZONTAL
        val lps = LinearLayoutCompat.LayoutParams(
            LinearLayoutCompat.LayoutParams.MATCH_PARENT,
            LinearLayoutCompat.LayoutParams.MATCH_PARENT
        )
        line.layoutParams = lps
        return line
    }

    //判断是否需要换行
    private fun judgmentNeedNewLine(
        paint: Paint,
        history: ArrayList<SearchHistoryModel>,
        index: Int,
        firstLineIndex: ArrayList<Int>,
        lineNum: Int
    ): Boolean {
        var isNeedLine = false
        var currentWidth = 0f
        for (i in firstLineIndex[lineNum - 1]..index) {
            currentWidth += ViewUtils.calcTextViewWidth(
                paint,
                history[i].searchWord
            ) + 3 * mPadding
            if (currentWidth > mLabelLimitWidth) {
                isNeedLine = true
                break
            }
        }

        return isNeedLine
    }

    override fun onResume() {
        super.onResume()

        ImmersionBar.with(this)
            .transparentBar()
            .statusBarDarkFont(true) //状态栏字体是深色，不写默认为亮色
            .navigationBarDarkIcon(true)
            .hideBar(BarHide.FLAG_HIDE_NAVIGATION_BAR)
            .navigationBarEnable(false)
            .init()
    }

    //搜索游戏
    private fun searchGame() {
        if (binding.etSearch.text.toString().isNullOrBlank()) {
            ToastUtils.showShort(this@GameSearchActivity, "搜索内容不能为空")
            return
        }
        if (mHistoryRecord.size == 0) {
            val word = SearchHistoryModel("${binding.etSearch.text}", 1)
            mHistoryRecord.add(word)
        } else {
            for (index in 0 until mHistoryRecord.size) {
                if (binding.etSearch.text.toString() == mHistoryRecord[index].searchWord) {
                    mHistoryRecord[index].searchCount++
                    break
                } else if (index == mHistoryRecord.size - 1) {
                    //为6个关键词时删除末尾的搜索关键字,替换为新的关键词
                    if (index == 5) {
                        mHistoryRecord.removeLast()
                    }
                    val word = SearchHistoryModel("${binding.etSearch.text}", 1)
                    mHistoryRecord.add(word)
                }
            }
        }

        val str = GsonUtils.toJson(mHistoryRecord)
        SPUtils.getInstance("history").put("searchHistory", str, true)

        obtainLocalHistory()
        //保存关键字
        KeyboardUtils.hideSoftInput(this)
        searchGame(binding.etSearch.text.toString())
    }

    override fun setListener() {
        binding.ivBack.clickWithTrigger {
            finish()
        }

        binding.tvSearch.clickWithTrigger(200) {
            searchGame()
        }

        binding.ivSearchDelete.clickWithTrigger {
            binding.rcvSearchGame.visibility = View.GONE
            binding.cltSearch.visibility = View.VISIBLE

            binding.etSearch.setText("")
        }

        binding.ivDelete.clickWithTrigger {
            //删除本地缓存历史记录
            SPUtils.getInstance("history").clear(true)
            binding.lltLabelsContainer.removeAllViews()
        }

        mTextWatcher = object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }

            override fun afterTextChanged(s: Editable?) {
                if (s?.length == 0) {
                    binding.rcvSearchGame.visibility = View.GONE
                    binding.cltSearch.visibility = View.VISIBLE
                }
            }
        }

        KeyboardUtils.registerSoftInputChangedListener(this) {
            if (it == 0) {
                binding.etSearch.clearFocus()
            }
        }

        binding.etSearch.addTextChangedListener(mTextWatcher)
        binding.etSearch.setOnEditorActionListener { v, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                searchGame()
            }
            true
        }
    }

    override fun onDestroy() {
        binding.etSearch.removeTextChangedListener(mTextWatcher)
        removeDisposables(this)
        super.onDestroy()
    }
}